import os
import json
from fastapi import APIRouter, Request, HTTPException, status
from application.utils import tools, aliyunclound, log
from application import settings
from captcha.image import ImageCaptcha
from io import BytesIO
import base64
from fastapi.params import Form
import random
import string
from ...utils.response_json import Success


logger = log.getLogger(os.environ.get('APP_NAME'))

app = APIRouter()


@app.get('/index')
def index() -> dict:
    return {'message': 'Welcome to the API'}


@app.get("/sms/{phone_number}", summary="发送短信验证码", description="发送短信验证码")
async def send_sms(request: Request, phone_number: str) -> dict:
    print(request.app)
    """发送短信验证码"""
    # 1 生成短信验证码
    sms_code = tools.genint(settings.SMS['CODE_LENGTH'])
    # 2 手机号和验证码存入redis
    redis = request.app.state.redis
    await redis.setex(f"sms:{phone_number}", settings.SMS['EXPIRE_TIME'], sms_code)
    # 3 发送短信
    aliyun = aliyunclound.AliYunClound(settings.SMS['ACCESS_KEY_ID'], settings.SMS['ACCESS_KEY_SECRET'])
    data = {
        'code': sms_code
    }
    result = await aliyun.sms_async(phone_number, data, settings.SMS['SIGN_NAME'], settings.SMS['TEMPLATE_ID'])
    print(result) #{'BizId': '823216829758356715^0', 'Code': 'OK', 'Message': 'OK', 'RequestId': '60535FAE-FCAD-5470-BD2A-1DA8A134548F'}
    print(type(result))
    if result.code != 'OK':
        logger.error(f"发送短信验证码到{phone_number}失败: {result.message}")
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                            detail=f"发送短信验证码到{phone_number}失败: {result.message}")
    # 4. 返回操作结果
    return {
        'code': 200,
        'message': '短信已发送，请留意手机',
        'status': 'Success',
    }


@app.get("/api/v1/auth/captcha")
async def get_captcha(request: Request):
    # Generate a random string for the CAPTCHA
    captcha_text = ''.join(random.choices(string.ascii_uppercase + string.digits, k=4))

    # Create a unique key for this CAPTCHA entry
    captcha_key = f"captcha:{random.getrandbits(64)}"

    # Store the CAPTCHA text in Redis with an expiration time
    redis = request.app.state.redis
    await redis.setex(captcha_key, settings.SMS['EXPIRE_TIME'], captcha_text)

    # Create and return the CAPTCHA image
    image = ImageCaptcha().generate_image(captcha_text)
    img_byte_arr = BytesIO()
    image.save(img_byte_arr, format='PNG')
    img_byte_arr = img_byte_arr.getvalue()
    img_byte_arr = base64.b64encode(img_byte_arr)
    mime_type = f"data:image/png;base64,"
    return Success(data={"captchaKey": captcha_key, "captchaBase64": mime_type + img_byte_arr.decode('utf-8')})


@app.post("/api/v1/auth/captcha")
async def verify_captcha(request: Request, captcha_input: str = Form(...), captcha_key: str = Form(...)):
    # Retrieve the CAPTCHA text from Redis
    correct_captcha_text = redis_client.get(captcha_key)

    if not correct_captcha_text:
        raise HTTPException(status_code=400, detail="CAPTCHA expired or invalid")

    # Validate the user's input against the stored CAPTCHA text
    if captcha_input.upper() == correct_captcha_text:
        # Delete the CAPTCHA entry from Redis after successful verification
        redis_client.delete(captcha_key)
        return {"message": "CAPTCHA verified successfully"}
    else:
        raise HTTPException(status_code=400, detail="Invalid CAPTCHA")
